﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace FwkLight.CodeExtensions
{
  public static class EnumerableExtensions
  {
    [DebuggerNonUserCode]
    public static bool IsNullOrEmpty ( this Array array )
    {
      return (array == null || array.Length == 0);
    }

    [DebuggerNonUserCode]
    public static string ToFormatedList ( this IEnumerable<string> list )
    {
      string msg = "";
      foreach (var str in list)
      {
        msg += str + Environment.NewLine;
      }

      return msg;
    }

    [DebuggerNonUserCode]
    public static bool IsNotEmpty<T> ( this IEnumerable<T> list )
    {
      return !list.IsEmpty();
    }

    [DebuggerNonUserCode]
    public static bool IsEmpty<T> ( this IEnumerable<T> list )
    {
      if (list == null) return true;
      return !list.Any();
    }

    [DebuggerNonUserCode]
    public static void ForEach<T> ( this IEnumerable list, Action<T> action ) where T : class
    {
      if (list == null) return;

      foreach (var item in list)
      {
        action(item as T);
      }
    }

    [DebuggerNonUserCode]
    public static void ForEach<T> ( this IEnumerable<T> list, Action<T> action )
    {
      if (list == null) return;
      foreach (T item in list)
      {
        action(item);
      }
    }

    [DebuggerNonUserCode]
    public static IEnumerable<T> For<T> ( this IEnumerable<T> list, Action<T, int> action )
    {
      if (list == null) return null;
      int index = 0;
      foreach (T item in list)
      {
        action(item, index);
        index++;
      }

      return list;
    }

    [DebuggerNonUserCode]
    public static void IfEmpty<T> ( this IEnumerable<T> list, Action action )
    {
      if (list.IsEmpty())
        action();
    }

    [DebuggerNonUserCode]
    public static IList<TOutput> ConvertAll<T, TOutput> ( this IEnumerable<T> list, Converter<T, TOutput> converter )
    {
      List<TOutput> returnList = new List<TOutput>();

      foreach (T item in list)
      {
        returnList.Add(converter(item));
      }

      return returnList;
    }

    [DebuggerNonUserCode]
    public static void Sort<T> ( this IList<T> list, IComparer<T> comparer ) where T : new()
    {
      if (list == null) return;
      if (list.Count <= 1) return;

      for (int i = 0; i < list.Count; i++)
      {
        for (int j = 0; j < list.Count; j++)
        {
          if (comparer.Compare(list[i], list[j]) < 0)
          {
            T temp = list[i];
            list[i] = list[j];
            list[j] = temp;
          }
        }
      }
    }

    [DebuggerNonUserCode]
    public static bool Contains<T> ( this IEnumerable<T> list, Func<T, bool> searcher ) where T : class
    {
      return (list.FirstOrDefault(searcher) != null);
    }

    [DebuggerNonUserCode]
    public static bool DoesNotContain<T> ( this IEnumerable<T> list, Func<T, bool> searcher ) where T : class
    {
      return !list.Contains(searcher);
    }
  }

}